#include <linux/init.h>             
#include <linux/module.h>          
#include <linux/kernel.h>   
 
#include <linux/fs.h>  
#include <asm/uaccess.h>  
#include <linux/firmware.h>  
  
#define DEVICE_NAME "mychardev"  
#define BUF_LEN 80  
  
static int Major;  
static char msg[BUF_LEN];  
static char *msg_Ptr;  
 
struct firmware *fw_handle;
 
MODULE_AUTHOR("Downey");
MODULE_DESCRIPTION("Linux kernel driver - hello_world PLUS!");
MODULE_VERSION("0.1");             //模块版本号
//指定license版本
MODULE_LICENSE("GPL");              
 
static char *name = "world";
module_param(name,charp,S_IRUGO);                                 //设置加载时可传入的参数
MODULE_PARM_DESC(name,"name,type: char *,permission: S_IRUGO");        //参数描述信息
 

static int my_open(struct inode *inode, struct file *file)  
{  
    static int counter = 0;  
  
    if (counter)  
        return -EBUSY;  
  
    counter++;  
    msg_Ptr = msg;  
    try_module_get(THIS_MODULE);  
  
    return 0;  
}  
  
static int my_release(struct inode *inode, struct file *file)  
{  
    module_put(THIS_MODULE);  
    return 0;  
}  
  
static ssize_t my_read(struct file *filp, char *buffer, size_t length, loff_t * offset)  
{  
    int bytes_read = 0;  
  
    if (*msg_Ptr == 0) {  
        return 0;  
    }  
    while (bytes_read < length && *msg_Ptr != 0) {  
        put_user(*(msg_Ptr++), buffer++);  
        bytes_read++;  
    }  
    return bytes_read;  
}
  
static struct file_operations fops = {  
    .read = my_read,  
    .open = my_open,  
    .release = my_release,  
};  
 



//设置初始化入口函数
static int __init hello_world_init(void)
{
    int ret ;
    printk(KERN_DEBUG "hello %s!!!\n",name);
    Major = register_chrdev(0, DEVICE_NAME, &fops);  
    if (Major < 0) {  
        printk(KERN_ALERT "Registering char device failed with %d\n", Major);  
        return Major;  
    } else {  
        printk(KERN_INFO "I was assigned major number %d.  To talk to\n", Major);   
        printk(KERN_INFO "the driver, create a dev file with\n");   
        printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);   
        printk(KERN_INFO "Try various minor numbers.  Don't forget to\n");   
        printk(KERN_INFO "rm the dev files and module when you're done.\n"); 
        printk(KERN_INFO "--------------------------------------------.\n"); 
	
    }     
                                    
    ret = request_firmware(&fw_handle, "my_firmware", NULL);
    if (ret) {
        printk(KERN_ERR "Failed to request firmware\n");
        return ret;
    }
    printk(KERN_INFO "Successfully requested firmware\n");

    return 0;
}
 
//设置出口函数
static void __exit hello_world_exit(void)
{
     release_firmware(fw_handle);
    printk(KERN_DEBUG "goodbye %s!!!\n",name);
    unregister_chrdev(Major, DEVICE_NAME);
}
 
//将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(hello_world_init);
module_exit(hello_world_exit);


